package com.xliang.spider.version04.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.xliang.spider.util.CommonEnum;
import com.xliang.spider.util.ConnectionUtil;
import com.xliang.spider.util.CookiesUtil;
import com.xliang.spider.util.HttpUtil;
import com.xliang.spider.version04.dao.SpiderChapterDao;
import com.xliang.spider.version04.dao.SpiderVideoDao;
import com.xliang.spider.version04.pojo.ChapterEntity;
import com.xliang.spider.version04.pojo.VideoEntity;
import com.xliang.spider.version04.service.SpiderVideoService;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.util.List;

/**
 * ${DESCRIPTION}
 *
 * @author xiongl
 * @create 2016-06-21 17:10
 */
@Service
public class SpiderVideoServiceImpl implements SpiderVideoService
{
    private static Logger logger = Logger.getLogger(SpiderVideoServiceImpl.class);
    
    @Resource
    private SpiderVideoDao spiderVideoDao;
    
    @Resource
    private SpiderChapterDao spiderChapterDao;
    
    @Override
    public void scanVideo()
        throws Exception
    {
        List<ChapterEntity> chapters = spiderChapterDao.findChapterList();
        if (chapters == null || chapters.isEmpty())
        {
            logger.info("没有发现可下载的视频");
        }
        for (ChapterEntity chapter : chapters)
        {
            logger.info("开始扫描 " + chapter.getChapterName() + "：" + chapter.getChapterUrl() + " 下的视频");
            Document document = null;
            try
            {
                document = ConnectionUtil.getConnection(chapter.getChapterUrl()).cookies(CookiesUtil.createJKCookies()).get();
            }
            catch (Exception e)
            {
                logger.error(chapter.getChapterName() + "  扫描失败", e);
            }
            if (document == null)
            {
                logger.info(chapter.getChapterName() + "  扫描失败");
                continue;
            }
            
            try
            {
                int videoCount = 0;
                Elements videoList = document.getElementsByClass("lesson-box").first().select("h2>a");
                for (Element video : videoList)
                {
                    boolean isContinue = false;
                    String videoName = video.text().trim().replaceAll("\\\\|:|\\*|\\?|\"|<|>|\\||\u000B|/n|/r|/t", "").replaceAll("/", "&");
                    String url = video.attr("href").trim();
                    Document videoDoc = null;
                    if (!url.startsWith("javascript"))
                    {
                        try
                        {
                            videoDoc = ConnectionUtil.getConnection(url).cookies(CookiesUtil.createJKCookies()).get();
                            isContinue = true;
                        }
                        catch (Exception e)
                        {
                            logger.error("获取【" + videoName + "】的下载地址发生异常", e);
                        }
                    }
                    if (videoDoc == null)
                    {
                        logger.info("获取【" + videoName + "】的下载地址失败");
                    }
                    VideoEntity videoEntity = new VideoEntity(chapter.getLessonName(), chapter.getChapterName(), chapter.getChapterId(), videoName, "");
                    if (isContinue)
                    {
                        String videoUrl = videoDoc.getElementsByTag("video").select("source").first().attr("src");
                        videoEntity.setVideoUrl(videoUrl);
                    }
                    else
                    {
                        videoEntity.setVideoUrl(url);
                    }
                    try
                    {
                        spiderVideoDao.insertVideo(videoEntity);
                        logger.info("新增视频：" + videoName);
                    }
                    catch (Exception e)
                    {
                        if (e.getMessage().contains("Duplicate") && e.getMessage().contains("uniq_lesson_name_and_chapter_id_and_video_name"))
                        {
                            spiderVideoDao.updateVideo(videoEntity);
                            logger.info("更新视频：" + videoEntity.getLessonName() + "————" + videoEntity.getChapterName() + "————" + videoEntity.getVideoName());
                        }
                        else
                        {
                            throw new Exception(e);
                        }
                    }
                    videoCount++;
                }
                if (videoCount == videoList.size())
                {
                    chapter.setStatus(1);
                    spiderChapterDao.updateChapterStatusById(chapter);
                    logger.info("课程：" + chapter.getChapterName() + " 下的视频已全部扫描完毕");
                }
            }
            catch (Exception e)
            {
                logger.error(e.getMessage(), e);
                chapter.setStatus(2);
                spiderChapterDao.updateChapterStatusById(chapter);
                logger.info("扫描课程：" + chapter.getChapterName() + " 发生异常，跳过");
            }
        }
    }
    
    @Override
    public void downloadVideo(String path)
        throws Exception
    {
        List<VideoEntity> videos = spiderVideoDao.findVideoList();
        for (VideoEntity video : videos)
        {
            if (video.getVideoUrl().endsWith(".mp4"))
            {
                String filePath = path + video.getLessonName() + "\\";
                File file = new File(filePath);
                if (!file.exists())
                {
                    file.mkdirs();
                }
                String fileName = file.getAbsolutePath() + "\\" + video.getChapterName() + "___" + video.getVideoName() + ".mp4";
                long startTime = System.currentTimeMillis();
                JSONObject jsonObject = HttpUtil.downLoadRemoteFile(video.getVideoUrl(), fileName);
                long endTime = System.currentTimeMillis();
                if (jsonObject.getIntValue("status") == CommonEnum.COMMON_IS.YES.getValue())
                {
                    video.setStatus(1);
                    logger.info("视频下载成功：" + video.getVideoName() + "，耗时：" + (endTime - startTime) / 1000 + "秒");
                    spiderVideoDao.updateVideoById(video);
                }
                else
                {
                    scanVideo(video);
                    logger.error("视频下载失败：" + video.getVideoName()+"，errorMessage="+jsonObject.getString("message"));
                }
            }
            else
            {
                logger.info(String.format("视频：%s 的下载网址：%s不正确，跳过", video.getVideoName(), video.getVideoUrl()));
                video.setStatus(2);
                spiderVideoDao.updateVideoById(video);
            }
        }
    }
    
    public void scanVideo(VideoEntity vo)
        throws Exception
    {
        ChapterEntity chapter = spiderChapterDao.findChapterByChapterIdAndLessonName(vo.getChapterId(), vo.getLessonName());
        try
        {
            Document document = null;
            try
            {
                document = ConnectionUtil.getConnection(chapter.getChapterUrl()).cookies(CookiesUtil.createJKCookies()).get();
            }
            catch (Exception e)
            {
                logger.error(chapter.getChapterName() + "  扫描失败", e);
            }
            if (document == null)
            {
                logger.info(chapter.getChapterName() + "  扫描失败");
            }
            Elements videoList = document.getElementsByClass("lesson-box").first().select("h2>a");
            for (Element video : videoList)
            {
                
                String videoName = video.text().trim().replaceAll("\\\\|:|\\*|\\?|\"|<|>|\\||\u000B|/n|/r|/t", "").replaceAll("/", "&");
                if (StringUtils.equals(vo.getVideoName(), videoName))
                {
                    boolean isContinue = false;
                    String url = video.attr("href").trim();
                    Document videoDoc = null;
                    if (!url.startsWith("javascript"))
                    {
                        try
                        {
                            videoDoc = ConnectionUtil.getConnection(url).cookies(CookiesUtil.createJKCookies()).get();
                            isContinue = true;
                        }
                        catch (Exception e)
                        {
                            logger.error("获取【" + videoName + "】的下载地址发生异常", e);
                        }
                    }
                    if (videoDoc == null)
                    {
                        logger.info("获取【" + videoName + "】的下载地址失败");
                    }
                    
                    VideoEntity videoEntity = new VideoEntity(chapter.getLessonName(), chapter.getChapterName(), chapter.getChapterId(), videoName, "");
                    if (isContinue)
                    {
                        String videoUrl = videoDoc.getElementsByTag("video").select("source").first().attr("src");
                        videoEntity.setVideoUrl(videoUrl);
                    }
                    else
                    {
                        videoEntity.setVideoUrl(url);
                    }
                    try
                    {
                        spiderVideoDao.insertVideo(videoEntity);
                        logger.info("新增视频：" + videoName);
                    }
                    catch (Exception e)
                    {
                        if (e.getMessage().contains("Duplicate") && e.getMessage().contains("uniq_lesson_name_and_chapter_id_and_video_name"))
                        {
                            spiderVideoDao.updateVideo(videoEntity);
                            logger.info("更新视频：" + videoEntity.getVideoName());
                        }
                        else
                        {
                            throw new Exception(e);
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            logger.error(e.getMessage(), e);
            chapter.setStatus(2);
            spiderChapterDao.updateChapterStatusById(chapter);
            logger.info("扫描课程：" + chapter.getChapterName() + " 发生异常，跳过");
        }
    }

    @Override
    public void updateVideoUrl()
        throws Exception
    {
        List<VideoEntity> videos = spiderVideoDao.findVideoList();
        for (VideoEntity video : videos)
        {
            scanVideo(video);
        }
    }

    public static void main(String[] args)
        throws Exception
    {
        Document document = ConnectionUtil.getConnection("http://www.jikexueyuan.com/course/2713.html").cookies(CookiesUtil.createJKCookies()).get();
        Elements videoList = document.getElementsByClass("lesson-box").first().select("h2>a");
        System.out.println(videoList);
        for (Element video : videoList)
        {
            String title = video.text();
            String url = video.attr("href");
            Document doc = ConnectionUtil.getConnection(url).cookies(CookiesUtil.createJKCookies()).get();
            String videoUrl = doc.getElementsByTag("video").select("source").first().attr("src");
            System.out.println(title + "：" + videoUrl);
        }
    }
}
